import * as THREE from 'three';
import polygonData from './polygonData.js'
const pointInPolygon = require('point-in-polygon');
import Delaunator from 'delaunator';
// import {lon2xyz} from "./math.js"
const model = new THREE.Group();
var pointArr = [];//处理多边形外轮顶点坐标，用于生成几何体顶点坐标
polygonData.forEach(item=>{
  pointArr.push(item[0],item[1],0)
})
// 生成轮廓线
const polygon = (pointArr)=>{
   //创建一个空的几何体对象
  const geometry = new THREE.BufferGeometry(); 
  geometry.attributes.position = new THREE.BufferAttribute(new Float32Array(pointArr), 3);
  const materialLine = new THREE.LineBasicMaterial({
    color: 0x006666,
  })
  var line = new THREE.LineLoop(geometry, materialLine);//首尾顶点连线，轮廓闭合
  // const materialPoint = new THREE.PointsMaterial({
  //   color: 0xffffff,
  //   size: 3,
  // })
  // const points = new THREE.Points(geometry, materialPoint);
  return [line]
}
// 生成网格点
const gridPoint = (polygonData)=>{
   var lonArr = [];//polygon的所有经度坐标
  var latArr = [];//polygon的所有纬度坐标
  polygonData.forEach(item=>{
    lonArr.push(item[0])
    latArr.push(item[1])
  })
  // 经纬度大小排序
  lonArr.sort((a,b)=>{return a-b})
  latArr.sort((a,b)=>{return a-b})
  // 获取经纬度的最大值、最小值
  var lonMin = lonArr[0]
  var lonMax = lonArr[lonArr.length-1]
  var latMin = latArr[0]
  var latMax = latArr[latArr.length-1]
  var rectPointsArr = [];//polygon对应的矩形轮廓内生成均匀间隔的矩形网格数据rectPointsArr
  // 在最大最小经纬度范围内生成点矩阵，每隔一个经纬度生成一个点
  for(var i= lonMin;i<lonMax +1;i++){
    for(var j= latMin;j<latMax + 1;j++){
      rectPointsArr.push([i,j])
    }
  }
  var polygonPointsArr = [];//处理点阵顶点坐标，用于生成几何体顶点坐标
  rectPointsArr.forEach(function (elem) {
    // 判断点是否在polygon内
    if(pointInPolygon(elem,polygonData)){
      polygonPointsArr.push(elem)
    }
  })
  // 将轮廓线上的点和内部的点合并
  return [...polygonData,...polygonPointsArr]
}
// 将网格点生成三角网格
const meshSanjiao = ()=>{
  // 轮廓线内部和线上的点
  const polygonPointsArr = gridPoint(polygonData)
  var posArr = [];//处理polygonPointsArr，作为几何体顶点三维坐标
  polygonPointsArr.forEach(function (elem) {
      posArr.push(elem[0], elem[1], 0)
  })
  const materialPoint = new THREE.PointsMaterial({
    color: 0xffffff,
    size: 3,
  })
  const geometryPoint = new THREE.BufferGeometry();
  geometryPoint.attributes.position = new THREE.BufferAttribute(new Float32Array(posArr), 3);
  const points = new THREE.Points(geometryPoint, materialPoint);
  model.add(points)
  // 三角剖分
  // 平面上一系列点集三角剖分，并获取三角形索引值
  var indexArr = new Delaunator(polygonPointsArr.flat()).triangles
  
  var usefulIndexArr = [];//二次处理后三角形索引，也就是保留多边形polygon内部三角形对应的索引
  for(var i=0;i<indexArr.length;i+=3){
    // 三角形顶点坐标
    var p1 = polygonPointsArr[indexArr[i]]
    var p2 = polygonPointsArr[indexArr[i+1]]
    var p3 = polygonPointsArr[indexArr[i+2]]
    // 三角形的中心点坐标
    var centerPoint = [(p1[0]+p2[0]+p3[0])/3,(p1[1]+p2[1]+p3[1])/3]
    // 判断这个中心点是否在polygon内
    if(pointInPolygon(centerPoint,polygonData)){
      usefulIndexArr.push(indexArr[i],indexArr[i+1],indexArr[i+2])
    }
  }
  // 三角形的全部索引值
  const indexes = new Uint16Array(usefulIndexArr)
  const geometry = new THREE.BufferGeometry();
  geometry.index = new THREE.BufferAttribute(indexes, 1);
  geometry.attributes.position = new THREE.BufferAttribute(new Float32Array(posArr), 3); 
  var material = new THREE.MeshBasicMaterial({
    color: 0x004444,
    side: THREE.DoubleSide, //背面可见，默认正面可见   THREE.DoubleSide：双面可见
    })
    // geometry.computeVertexNormals();//如果使用受光照影响材质，需要计算生成法线
    var mesh = new THREE.Mesh(geometry, material)
    mesh.position.z = -0.01;
    // 渲染三角形线框
    var mesh2 = mesh.clone();
    mesh2.material = new THREE.MeshBasicMaterial({
        color: 0x009999,
        wireframe: true,
    })
    mesh.position.z = -0.02;
    const group = new THREE.Group();
    group.add(mesh,mesh2)
    return group
}
model.add(...polygon(pointArr),meshSanjiao())
export {model};